# -*- coding: UTF-8 -*-
'''
A module with a registry of link resolver objects.

The link resolver objects know how to resolve links from a tvshack.cc webpage into
playable streams. This may involve executing some HTTP requests to other websites.

This registry will maintain a list of known resolvers to make it easier to extend
the plugin with more supported video hosting websites.

Current list of link resolvers include:
 - tweety: can resolve 56.com, google video, tudou.com, veoh
 - youku: resolves youku links
 - megavideo: to resolve megavideo links. with support for megavideo premium accounts
 - movshare: resolves movshare and stagevu links
 - youtube: resolves youtube links
 - videoweed: resolves videoweed and novamov links
 - divxden: resolves divxden links
 
@author: pguedes 
'''
from plugin import PluginMovieItem
import logging, utils.htmlutils as http, re
import megavideo, youku, tweety, movshare, youtube, zshare, videoweed, divxden

log = logging.getLogger("linkresolvers")
resolvers = [megavideo, tweety, zshare, movshare, videoweed, youtube, youku, divxden]
resolversMap = {'56': tweety, 'google': tweety, 'tudou': tweety, 'veoh': tweety,
                'movshare': movshare, 'stagevu': movshare,
                'videoweed': videoweed, 'novamov': videoweed,
                'youtube': youtube,
                'megavideo': megavideo,
                'youku': youku,
                'divxden': divxden}

def isSupported(source): 
  return resolversMap.has_key(source)

class UnresolvableSourceException(Exception):
  pass

class LoopingLinkResolver(object):
  """
  Loops thru all available link resolvers trying to resolve the file with each one. 
  """
  def resolve(self, page):
    '''
    Try to resolve a link into a playable stream url
    This will run through all registered linkresolvers trying one by one. The first one to succeed will return.
    @param page: the html of the webpage that resolvers can parse
    @return: a list of urls with playable streams
    '''
    for resolver in resolvers:
      try:
        log.debug("Attempting to resolve links with the '%s' resolver" % str(resolver))
        links = resolver.resolve(page)
        if links is not None and len(links) > 0:
          log.debug("Successfully resolved to: %s" % str(links));
          return links
      except:
        log.exception("Failed to resolve links with the '%s' resolver" % str(resolver))

class Source(object):
  """
  Represents a TvShack source and is able to resolve into url's for the player.
  A source maps to a host on the internet. For example, a source for a certain
  movie may be megavideo, and in this source a list of possibly resolvable links
  may exist. Resolving a source shall attempt to resolve each of these links
  returning the list of parts from the first one that successfully resolves.
  """
  def __init__(self, urls, type, metadata):
    log.warning("type: %s" % str(type))
    if not resolversMap.has_key(type):
      log.warning("No resolver found for type: %s" % str(type))
      self.__resolver = LoopingLinkResolver()
    else:
      self.__resolver = resolversMap[type]
    self.__sourceName = type
    self.__urls = urls
    self.__metadata = metadata
    
  def __resolveAlternate(self, name, url):
    log.debug("Listing parts for '%s' at %s" % (name, url))
    html = http.get(url)
    parts = re.compile('<a href="javascript:changevid.(.+?).;"').findall(html)
    idtag = re.compile("http://tvshack.cc/video_load/(.+?)/(.+?)/'").findall(html)
    log.debug("Found video idtag: '%s'" % str(idtag))
    links = []
    if len(parts) < 1:
      raise UnresolvableSourceException("No playable parts found!")
    elif len(parts) < 2:
      videourl = 'http://tvshack.cc/video_load/%s/%s/%s/' % (idtag[0][0], idtag[0][1], 1)
      links.extend([PluginMovieItem(name, url, metadata=self.__metadata) for url in self.__resolveLinks(videourl)])
    else:
      for pnumb in parts:
        videourl = 'http://tvshack.cc/video_load/%s/%s/%s/' % (idtag[0][0], idtag[0][1], pnumb)
        videoname = '%s - Part %s' % (name, pnumb)
        links.extend([PluginMovieItem(videoname, url, metadata=self.__metadata) for url in self.__resolveLinks(videourl)])
        
    if links:
      log.debug("Found part items: %s" % links)
      return links
    raise UnresolvableSourceException("No links found for '%s' on host '%s'" % (url, self.__sourceName))    
    
  def resolve(self):
    """
    Will resolve one of the available alternate versions of a playable item
    """
    name = self.__metadata.getTitle()
    for url in self.__urls:
      try:
        return self.__resolveAlternate(name, url)
      except:
        log.exception("Failed to resolve alternate link")
    raise UnresolvableSourceException("No links found for '%s' on %s" % (name, self.__sourceName))

  def __resolveLinks(self, url):
    return self.__resolver.resolve(http.get(url, True))
